// import { compileTemplate } from '@vue/component-compiler-utils';
import { compileTemplate, compileScript, parse } from '@vue/compiler-sfc';

const ScriptSetupPattern = /<(script)(?:.* \bsetup\b)?[^>]*>([\s\S]+)<\/\1>/;
function stripScript(content, id) {
	const result = content.match(ScriptSetupPattern);
	const source = result && result[0] ? result[0].trim() : '';
	if (source) {
		const { descriptor } = parse(source);
		const { content: scriptContent } = compileScript(descriptor, {
			refSugar: true,
			id,
		});
		return scriptContent;
	}
	return source;
}

function stripStyle(content) {
	const result = content.match(/<(style)\s*>([\s\S]+)<\/\1>/);
	return result && result[2] ? result[2].trim() : '';
}

// 编写例子时不一定有 template。所以采取的方案是剔除其他的内容
function stripTemplate(content) {
	content = content.trim();
	if (!content) {
		return content;
	}
	return content.replace(/<(script|style)[\s\S]+<\/\1>/g, '').trim();
}

function pad(source) {
	return source
		.split(/\r?\n/)
		.map((line) => `  ${line}`)
		.join('\n');
}

function genInlineComponentText(template, script, id) {
	const finalOptions = {
		id: `inline-component-${id}`,
		source: `${template}`,
		filename: `inline-component-${id}`,
		// compiler: TemplateCompiler,
		compilerOptions: {
			mode: 'function',
		},
	};
	const compiledComponent = compileTemplate(finalOptions);
	// tips
	if (compiledComponent.tips && compiledComponent.tips.length) {
		compiledComponent.tips.forEach((tip) => {
			console.warn(tip);
		});
	}
	// errors
	if (compiledComponent.errors && compiledComponent.errors.length) {
		console.error(
			`\n  Error compiling template:\n${pad(compiledComponent.source)}\n` + compiledComponent.errors.map((e) => `  - ${e}`).join('\n') + '\n'
		);
	}
	let demoComponentContent = `
		${compiledComponent.code.replace('return function render', 'function render')}
	  `;
	// todo: 这里采用了硬编码有待改进
	script = script.trim();
	if (script) {
		script = script
			.replace(/export\s+default/, 'const democomponentExport =')
			.replace(/import ({.*}) from 'vue'/g, (s, s1) => `const ${s1} = Vue`)
			.replace(/const ({ defineComponent as _defineComponent }) = Vue/g, 'const { defineComponent: _defineComponent } = Vue');
	} else {
		script = 'const democomponentExport = {}';
	}
	demoComponentContent = `(function() {
    ${demoComponentContent}
    ${script}
    return {
      render,
      ...democomponentExport
    }
  })()`;
	return demoComponentContent;
}

export { stripScript, stripStyle, stripTemplate, genInlineComponentText };
